/*
 * @Author: shenya shenya0203@163.com
 * @Date: 2024-04-16 10:22:21
 * @LastEditors: shenya shenya0203@163.com
 * @LastEditTime: 2024-04-16 13:07:57
 * @FilePath: /code/src/queue.c
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
#include "queue.h"

void initializeMessageQueue(MessageQueue *mq)
{
    mq->front = -1;
    mq->rear = -1;
    pthread_mutex_init(&mq->mutex, NULL);
    pthread_cond_init(&mq->cond, NULL);
}

int isMessageQueueEmpty(MessageQueue *mq)
{
    return (mq->front == -1 && mq->rear == -1);
}

int isMessageQueueFull(MessageQueue *mq)
{
    return ((mq->rear + 1) % MAX_MESSAGE_COUNT == mq->front);
}

void enqueueMessage(MessageQueue *mq, const char *data, int length)
{
    pthread_mutex_lock(&mq->mutex);

    while (isMessageQueueFull(mq))
    {
        pthread_cond_wait(&mq->cond, &mq->mutex);
    }

    if (isMessageQueueEmpty(mq))
    {
        mq->front = mq->rear = 0;
    }
    else
    {
        mq->rear = (mq->rear + 1) % MAX_MESSAGE_COUNT;
    }

    strncpy(mq->messages[mq->rear].data, data, MAX_MESSAGE_LENGTH);
    mq->messages[mq->rear].length = length;

    pthread_cond_signal(&mq->cond);
    pthread_mutex_unlock(&mq->mutex);
}

void enqueueMessageIndex(MessageQueue *mq, const char *data, int length, MessageIndex messIndex)
{
    pthread_mutex_lock(&mq->mutex);

    while (isMessageQueueFull(mq))
    {
        pthread_cond_wait(&mq->cond, &mq->mutex);
    }

    if (isMessageQueueEmpty(mq))
    {
        mq->front = mq->rear = 0;
    }
    else
    {
        mq->rear = (mq->rear + 1) % MAX_MESSAGE_COUNT;
    }

    // strncpy(mq->messages[mq->rear].data + 0, (char*)&index, sizeof(uint16_t));
    // strncpy(mq->messages[mq->rear].data + 2, (char*)&count, sizeof(uint16_t));
    // strncpy(mq->messages[mq->rear].data + 4, (char*)&type, sizeof(uint16_t));
    // strncpy(mq->messages[mq->rear].data + 0, (char *)&messIndex, sizeof(MessageIndex));
    // strncpy(mq->messages[mq->rear].data + 24, data, length);
    memcpy(mq->messages[mq->rear].data + 0, (char *)&messIndex, sizeof(MessageIndex));
    memcpy(mq->messages[mq->rear].data + 24, data, length);
    mq->messages[mq->rear].length = length;
    MessageIndex* msg = (MessageIndex*)(mq->messages[mq->rear].data);
    printf("en index:%d\n", msg->index);

    pthread_cond_signal(&mq->cond);
    pthread_mutex_unlock(&mq->mutex);
}

Message dequeueMessage(MessageQueue *mq)
{
    Message emptyMessage;
    emptyMessage.length = 0;

    pthread_mutex_lock(&mq->mutex);

    while (isMessageQueueEmpty(mq))
    {
        pthread_cond_wait(&mq->cond, &mq->mutex);
    }

    if (mq->front == mq->rear)
    {
        Message dequeuedMessage = mq->messages[mq->front];
        mq->front = mq->rear = -1;

        pthread_cond_signal(&mq->cond);
        pthread_mutex_unlock(&mq->mutex);

        return dequeuedMessage;
    }
    else
    {
        Message dequeuedMessage = mq->messages[mq->front];
        mq->front = (mq->front + 1) % MAX_MESSAGE_COUNT;

        pthread_cond_signal(&mq->cond);
        pthread_mutex_unlock(&mq->mutex);

        return dequeuedMessage;
    }
}
